import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { Component, Input, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { WizardModule } from './wizard.module';

@Component({
  template: `
    <lv-wizard
      [lvMode]="lvMode"
      [lvSize]="lvSize"
      [lvLabelPlacement]="lvLabelPlacement"
      [lvStatus]="lvStatus"
      [lvActiveIndex]="lvActiveIndex"
      [lvStartNumber]="lvStartNumber"
    >
      <lv-wizard-step>Wizard 01</lv-wizard-step>
      <lv-wizard-step>Wizard 02</lv-wizard-step>
      <lv-wizard-step>Wizard 03</lv-wizard-step>
    </lv-wizard>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
class TestWizardComponent {
  @Input() lvMode: string = 'number';
  @Input() lvSize: string = 'default';
  @Input() lvLabelPlacement: string = 'vertical';
  @Input() lvStatus: string;
  @Input() lvActiveIndex: number = 0;
  @Input() lvStartNumber: number = 1;
}

describe('WizardComponent', () => {
  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        declarations: [TestWizardComponent],
        imports: [WizardModule],
        teardown: { destroyAfterEach: true },
      }).compileComponents();
    })
  );

  describe('render', () => {
    let component: TestWizardComponent;
    let fixture: ComponentFixture<TestWizardComponent>;
    let cdr: ChangeDetectorRef;

    const renderComponent = param => {
      for (const [key, value] of Object.entries(param)) {
        component[key] = value;
      }
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();
    };

    beforeEach(() => {
      fixture = TestBed.createComponent(TestWizardComponent);
      component = fixture.componentInstance;
      cdr = fixture.debugElement.injector.get(ChangeDetectorRef);
    });

    // 不同模式（number和icon）渲染
    it('with lvMode and lvStartNumber', () => {
      renderComponent({ lvStartNumber: 2 });
      renderComponent({ lvMode: 'icon' });
    });

    // 大小尺寸渲染渲染
    it('with lvSize and lvActiveIndex', () => {
      renderComponent({ lvSize: 'small', lvActiveIndex: '2' });
    });

    // 标签放置位置渲染
    it('with lvLabelPlacement', () => {
      renderComponent({ lvLabelPlacement: 'horizontal' });
    });

    // 当前步骤状态渲染
    it('with status', () => {
      renderComponent({ lvStatus: 'wait' });
      renderComponent({ lvStatus: 'process' });
      renderComponent({ lvStatus: 'finish' });
      renderComponent({ lvStatus: 'error' });
    });
  });

  describe('work', () => {
    let component: TestWizardComponent;
    let fixture: ComponentFixture<TestWizardComponent>;
    let cdr: ChangeDetectorRef;
    const stepClass = '.lv-wizard-step';

    beforeEach(() => {
      fixture = TestBed.createComponent(TestWizardComponent);
      component = fixture.componentInstance;
      cdr = fixture.debugElement.injector.get(ChangeDetectorRef);
    });

    // Steps能正常切换
    it('should switch normally', () => {
      component.lvActiveIndex = 1;
      fixture.detectChanges();

      const steps = document.querySelectorAll(stepClass);
      expect(steps[0].className).toContain('lv-wizard-step-finish');
      expect(steps[1].className).toContain('lv-wizard-step-process');

      component.lvActiveIndex = 2;
      cdr.detectChanges();
      expect(steps[0].className).toContain('lv-wizard-step-finish');
      expect(steps[1].className).toContain('lv-wizard-step-finish');
      expect(steps[2].className).toContain('lv-wizard-step-process');
    });
  });
});
